#include "disk.h"
#include "daemon.h"
#include "action.h"
#include "tuboxfile.h"

#include <QFile>
#include <QDir>

#include <iostream>
using std::cerr;
using std::cout;
using std::endl;

namespace Tubox {

Disk::Disk(const QString &absolutePath, Daemon* daemon) : Folder("",""), absolutePath(absolutePath), daemon(daemon) { }

Disk::~Disk() { }

/**
 * Check if actual disk is equal to server disk.
 */

QList<Action *> Disk::check() {
	TuboxFile tuboxFile(absolutePath, "");
	return tuboxFile.check();
}

void Disk::save(File& file, const bool saveData) throw(FileSystemError) {
	QString realPath = absolutePath + "/" + file.getFullPath();
	if(saveData) {
		/* Save via QFile	 */
		QFile qfile(realPath);
		if(!qfile.open(QIODevice::ReadWrite))
			throw FileSystemError("save(File) qfile opening error.",file);
		if(qfile.write((file.getData())) == qint64(-1)) {
			throw FileSystemError("save(File) qfile writing error.",file);
		}
	}
	TuboxFile tbFile(absolutePath, file.getPath());
	tbFile.add(file);
}

void Disk::remove(const File& file) throw(FileSystemError) {
	QString realPath = absolutePath + "/" + file.getFullPath();
	QFile qfile(realPath);
	qfile.remove();
	TuboxFile tbFile(absolutePath, file.getPath());
	tbFile.remove(file);
}

void Disk::remove(const Folder& folder) throw(FileSystemError) {
	QDir parentDir(absolutePath + "/" + folder.getPath());
	TuboxFile tbFile(absolutePath, folder.getPath());
	tbFile.remove(folder);
	if(!parentDir.rmdir(folder.getName())) {
		throw FileSystemError("remove(Folder) error.",folder);
	}
}

void Disk::move(const QString& oldPath, const QString& newPath) throw(FileSystemError) {
	QFileInfo oldEntry(oldPath);
	QString nonConstOldPath(oldPath);
	QString nonConstNewPath(newPath);
	if(oldEntry.isFile())
		move(File(nonConstOldPath,0,0), File(nonConstNewPath,0,0));
	else
		move(Folder(oldPath,0), Folder(newPath,0));
}

void Disk::move(const Folder& oldFolder, const Folder& newFolder) throw(FileSystemError) {
	QDir oldDir(absolutePath + "/" + oldFolder.getFullPath());
	if(!oldDir.rename(oldDir.absolutePath(),absolutePath + "/" + newFolder.getFullPath()))
		throw FileSystemError("move(Folder,Folder) error", oldFolder, newFolder);
}

void Disk::move(const File& oldFile, const File& newFile) throw(FileSystemError) {	//TODO FIXME
	QString oldRealPath = absolutePath + "/" + oldFile.getFullPath();
	QString newRealPath = absolutePath + "/" + newFile.getFullPath();
	QFile qOldFile(oldRealPath);
	qOldFile.open(QIODevice::ReadWrite);
	qOldFile.close();
	if(!qOldFile.rename(newRealPath))
		throw FileSystemError("move(File,File) error. :D", oldFile, newFile);
}

void Disk::update(File& file, const bool saveData) throw(FileSystemError) {
	QString realPath = absolutePath + "/" + file.getFullPath();
	QFile qfile(realPath);
	if(qfile.exists() && saveData) {
		if(!qfile.remove()) {
			throw FileSystemError("update(File) old file removing error.", file);
		}
	}
	save(file, saveData);
}

void Disk::create(const Folder& folder) throw(FileSystemError) {
	QDir parentDir(absolutePath + "/" + folder.getPath());
	if(!parentDir.mkdir(folder.getName()))
		throw FileSystemError("create(Foler)",folder);
	TuboxFile tbFile(absolutePath, folder.getPath());
	tbFile.add(folder);
}

}

